home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / ck5a189s / ckuusr.c < prev    next >
C/C++ Source or Header  |  1993-06-26  |  57KB  |  2,066 lines

  1. char *userv = "User Interface 5A(103), 26 Jun 93";
  2.  
  3. /*  C K U U S R --  "User Interface" for Unix Kermit (Part 1)  */
  4.  
  5. /*
  6.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  7.   Columbia University Academic Information Systems, New York City.
  8.  
  9.   Copyright (C) 1985, 1993, Trustees of Columbia University in the City of New
  10.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  11.   sold for profit as a software product itself, nor may it be included in or
  12.   distributed with commercial products or otherwise distributed by commercial
  13.   concerns to their clients or customers without written permission of the
  14.   Office of Kermit Development and Distribution, Columbia University.  This
  15.   copyright notice must not be removed, altered, or obscured.
  16. */
  17.  
  18. /*
  19.   NOTE: Because of the massive additions in functionality, and therefore
  20.   the increase in the number of commands, much code was moved from here to
  21.   the two new modules, ckuus4.c and ckuus5.c.  This module now contains only
  22.   the top-level command keyword table, the SET command keyword table, and
  23.   the top-level interactive command parser/dispatcher.  ckuus3.c contains the
  24.   rest of the SET and REMOTE command parsers; ckuus2.c contains the help
  25.   command parser and help text strings, and ckuus4.c and ckuus5.c contain
  26.   miscellaneous pieces that logically belong in the ckuusr.c file but had to
  27.   be moved because of size problems with some C compilers / linkers.
  28.   Later...  as the other modules became too large, a ckuus6.c was created.
  29.   Still later...  ckuus7.c.
  30.   Also: ckuusy.c contains the UNIX-style command-line interface;
  31.   ckuusx.c contains routines needed by both the command-line interface and
  32.   the interactive command parser.
  33. */
  34.  
  35. /*
  36.  The ckuus*.c modules depend on the existence of C library features like fopen,
  37.  fgets, feof, (f)printf, argv/argc, etc.  Other functions that are likely to
  38.  vary among Unix implementations -- like setting terminal modes or interrupts
  39.  -- are invoked via calls to functions that are defined in the system-
  40.  dependent modules, ck?[ft]io.c.  The command line parser processes any
  41.  arguments found on the command line, as passed to main() via argv/argc.  The
  42.  interactive parser uses the facilities of the cmd package (developed for this
  43.  program, but usable by any program).  Any command parser may be substituted
  44.  for this one.  The only requirements for the Kermit command parser are these:
  45.  
  46. 1. Set parameters via global variables like duplex, speed, ttname, etc.  See
  47.    ckmain.c for the declarations and descriptions of these variables.
  48.  
  49. 2. If a command can be executed without the use of Kermit protocol, then
  50.    execute the command directly and set the variable sstate to 0. Examples
  51.    include 'set' commands, local directory listings, the 'connect' command.
  52.  
  53. 3. If a command requires the Kermit protocol, set the following variables:
  54.  
  55.     sstate                             string data
  56.       'x' (enter server mode)            (none)
  57.       'r' (send a 'get' command)         cmarg, cmarg2
  58.       'v' (enter receive mode)           cmarg2
  59.       'g' (send a generic command)       cmarg
  60.       's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  61.       'c' (send a remote host command)   cmarg
  62.  
  63.     cmlist is an array of pointers to strings.
  64.     cmarg, cmarg2 are pointers to strings.
  65.     nfils is an integer.
  66.  
  67.     cmarg can be a filename string (possibly wild), or
  68.        a pointer to a prefabricated generic command string, or
  69.        a pointer to a host command string.
  70.     cmarg2 is the name to send a single file under, or
  71.        the name under which to store an incoming file; must not be wild.
  72.        If it's the name for receiving, a null value means to store the
  73.        file under the name it arrives with.
  74.     cmlist is a list of nonwild filenames, such as passed via argv.
  75.     nfils is an integer, interpreted as follows:
  76.       -1: filespec (possibly wild) in cmarg, must be expanded internally.
  77.        0: send from stdin (standard input).
  78.       >0: number of files to send, from cmlist.
  79.  
  80.  The screen() function is used to update the screen during file transfer.
  81.  The tlog() function writes to a transaction log.
  82.  The debug() function writes to a debugging log.
  83.  The intmsg() and chkint() functions provide the user i/o for interrupting
  84.    file transfers.
  85. */
  86.  
  87. #ifndef NOICP
  88. /* Includes */
  89.  
  90. #include "ckcdeb.h"
  91. #include "ckcasc.h"
  92. #include "ckcker.h"
  93. #include "ckuusr.h"
  94. #include "ckcxla.h"
  95. #include "ckcnet.h"            /* Network symbols */
  96.  
  97. #ifdef datageneral
  98. #include <packets:common.h>
  99. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  100. #endif /* datageneral */
  101.  
  102. /* External Kermit Variables, see ckmain.c for description. */
  103.  
  104. extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg, 
  105.   escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho;
  106.  
  107. extern long vernum;
  108. extern char *versio;
  109. extern char *ckxsys, *cmarg, *cmarg2, **cmlist;
  110. #ifndef NOHELP
  111. extern char *introtxt[];
  112. extern char *newstxt[];
  113. #endif /* NOHELP */
  114. extern char *PWDCMD, *WHOCMD, *TYPCMD;
  115. extern char ttname[];
  116. #ifndef NOFRILLS
  117. extern int rmailf;            /* MAIL command items */
  118. extern char optbuf[];
  119. #endif /* NOFRILLS */
  120. extern CHAR sstate;
  121.  
  122. #ifdef NETCONN
  123. extern int network;            /* Have active network connection */
  124. #endif /* NETCONN */
  125.  
  126. #ifndef NOMSEND                /* Multiple SEND */
  127. extern char *msfiles[];
  128. #endif /* NOMSEND */
  129. extern char fspec[];            /* Most recent filespec */
  130.  
  131. #ifndef NOCSETS
  132. extern int nfilc;
  133. extern struct keytab fcstab[];
  134. #endif /* NOCSETS */
  135.  
  136. int rcflag = 0;                /* Pointer to home directory string */
  137. int repars,                /* Reparse needed */
  138.     techo = 0;                /* Take echo */
  139. #ifndef NOSCRIPT
  140. int secho = 1;
  141. #endif /* NOSCRIPT */
  142.  
  143. #ifndef NOXMIT
  144. /* Variables for TRANSMIT command */
  145.  
  146. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  147. int xmitf = 0;            /* Character to fill empty lines */
  148. int xmitl = 0;            /* 0 = Don't send linefeed too */
  149. int xmitp = LF;            /* Host line prompt */
  150. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  151. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  152. #endif /* NOXMIT */
  153.  
  154. /* Declarations from ck?fio.c module */
  155.  
  156. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  157.  
  158. /* Command-oriented items */
  159.  
  160. #ifdef DCMDBUF
  161. extern char *cmdbuf;            /* Command buffers */
  162. extern char *atmbuf;
  163. extern char *line;            /* Character buffer for anything */
  164. extern char *tmpbuf;            /* Short temporary string buffer */
  165. extern int *ifcmd;
  166. extern int *intime;
  167. #else
  168. extern char cmdbuf[];            /* Command buffers */
  169. extern char atmbuf[];
  170. extern char line[];            /* Character buffer for anything */
  171. extern char tmpbuf[];            /* Temporary buffer */
  172. extern int ifcmd[];
  173. extern int intime[];
  174. #endif /* DCMDBUF */
  175.  
  176. char *lp;                /* Pointer to line buffer */
  177.  
  178. #ifndef NOSPL
  179. extern char inpbuf[];            /* Buffer for INPUT and REINPUT */
  180. char *inpbp = inpbuf;            /* And pointer to same */
  181. extern char lblbuf[];            /* Buffer for labels */
  182. #endif /* NOSPL */
  183.  
  184. char psave[80] = { NUL };        /* For saving & restoring prompt */
  185.  
  186. extern int success;            /* Command success/failure flag */
  187.  
  188. #ifndef NOSPL
  189. int                    /* SET INPUT parameters. */
  190. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  191.   indef = 1,                /* default timeout, seconds */
  192.   inecho = 1,                /* 1 = echo on */
  193.   insilence = 0;            /* 0 = no silence constraint */
  194.  
  195. int maclvl = -1;            /* Macro nesting level */
  196. int mecho = 0;                /* Macro echo, 0 = don't */
  197. char varnam[6];                /* For variable names */
  198. extern int macargc[];            /* ARGC from macro invocation */
  199.  
  200. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  201.  
  202. extern char **a_ptr[];            /* Array pointers */
  203. extern int a_dim[];            /* Array dimensions */
  204.  
  205. #ifdef DCMDBUF
  206. extern struct cmdptr *cmdstk;        /* The command stack itself */
  207. #else
  208. extern struct cmdptr cmdstk[];        /* The command stack itself */
  209. #endif /* DCMDBUF */
  210. extern int cmdlvl;            /* Current position in command stack */
  211. #endif /* NOSPL */
  212.  
  213. static int x, y, z = 0;            /* Local workers */
  214. static char *s;
  215.  
  216. #define xsystem(s) zsyscmd(s)
  217.  
  218. /* Top-Level Interactive Command Keyword Table */
  219.  
  220. struct keytab cmdtab[] = {
  221. #ifndef NOPUSH
  222.     "!",       XXSHE, CM_INV,    /* shell escape */
  223. #endif /* NOPUSH */
  224.     "#",           XXCOM, CM_INV,    /* comment */
  225. #ifndef NOSPL
  226.     ":",           XXLBL, CM_INV,    /* label */
  227. #endif /* NOSPL */
  228. #ifndef NOPUSH
  229.     "@",           XXSHE, CM_INV,    /* DCL escape */
  230. #endif /* NOPUSH */
  231. #ifndef NOSPL
  232.     "apc",         XXAPC, 0,        /* Application Program Command */
  233.     "asg",         XXASS, CM_INV,       /* invisible synonym for ASSIGN */
  234.     "ask",         XXASK, 0,        /* ASK for text, assign to variable */
  235.     "askq",        XXASKQ,0,            /* ASK quietly (no echo) */
  236.     "assign",      XXASS, 0,            /* ASSIGN value to variable or macro */
  237. #endif /* NOSPL */
  238. #ifndef NOFRILLS
  239.     "bug",         XXBUG, 0,        /* BUG report instructions */
  240. #endif /* NOFRILLS */
  241.     "bye",         XXBYE, 0,        /* BYE to remote server */
  242.     "c",           XXCON, CM_INV|CM_ABR, /* invisible synonym for CONNECT */
  243. #ifndef NOFRILLS
  244.     "cat",         XXTYP, CM_INV,    /* Invisible synonym for TYPE */
  245. #endif /* NOFRILLS */
  246.     "cd",          XXCWD, 0,        /* Change Directory */
  247.     "check",       XXCHK, 0,        /* CHECK for a feature */
  248. #ifndef NOFRILLS
  249.     "clear",       XXCLE, 0,        /* CLEAR input and/or device buffer */
  250. #endif /* NOFRILLS */
  251.     "close",       XXCLO, 0,        /* CLOSE a log or other file */
  252. #ifdef NOFRILLS
  253.     "comment",     XXCOM, CM_INV,    /* Introduce a comment */
  254. #else
  255.     "comment",     XXCOM, 0,        /* COMMENT */
  256. #endif /* NOFRILLS */
  257.     "connect",     XXCON, 0,        /* Begin terminal connection */
  258.     "cwd",       XXCWD, CM_INV,    /* Invisisble synonym for cd */
  259. #ifndef NOSPL
  260.     "dcl",         XXDCL, CM_INV,    /* DECLARE an array */
  261.     "declare",     XXDCL, 0,        /* DECLARE an array */
  262.     "decrement",   XXDEC, 0,        /* DECREMENT a numeric variable */
  263.     "define",      XXDEF, 0,        /* DEFINE a macro or variable */
  264. #endif /* NOSPL */
  265. #ifndef NOFRILLS
  266.     "delete",      XXDEL, 0,        /* DELETE a file */
  267. #endif /* NOFRILLS */
  268. #ifndef NODIAL
  269.     "dial",       XXDIAL,0,        /* DIAL a phone number */
  270. #endif /* NODIAL */
  271. #ifndef MAC
  272.     "directory",   XXDIR, 0,        /* DIRECTORY of files */
  273. #endif /* MAC */
  274. #ifndef NOFRILLS
  275.     "disable",     XXDIS, 0,        /* DISABLE a server function */
  276. #endif /* NOFRILLS */
  277. #ifndef NOSPL
  278.     "do",          XXDO,  0,        /* DO (execute) a macro */
  279. #endif /* NOSPL */
  280. #ifndef NOFRILLS
  281.     "e-packet",    XXERR, CM_INV,    /* Send an Error-Packet */
  282. #endif /* NOFRILLS */
  283.     "echo",        XXECH, 0,        /* ECHO text */
  284. #ifndef NOSPL
  285.     "else",        XXELS, CM_INV,    /* ELSE part of IF statement */
  286. #endif /* NOSPL */
  287. #ifndef NOFRILLS
  288.     "enable",      XXENA, 0,        /* ENABLE a server function */
  289. #endif /* NOFRILLS */
  290. #ifndef NOSPL
  291.     "end",         XXEND, 0,        /* END command file or macro */
  292. #endif /* NOSPL */
  293.     "ex",          XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */
  294.     "exit",       XXEXI, 0,         /* EXIT from C-Kermit */
  295.     "extproc",     XXCOM, CM_INV,        /* Dummy command for OS/2 */
  296.     "f",           XXFIN, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  297.     "finish",      XXFIN, 0,         /* FINISH */
  298. #ifndef NOSPL
  299.     "fo",          XXFOR, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  300.     "for",         XXFOR, 0,        /* FOR loop */
  301. #endif /* NOSPL */
  302. #ifndef NOFRILLS
  303. #ifndef MAC
  304.     "fot",       XXDIR, CM_INV,    /* "fot" = "dir" (for Chris) */
  305. #endif /* MAC */
  306. #endif /* NOFRILLS */
  307.     "g",           XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */
  308. #ifndef NOSPL
  309.     "ge",          XXGET, CM_INV|CM_ABR, /* Ditto */
  310. #endif /* NOSPL */
  311.     "get",         XXGET, 0,        /* GET */
  312. #ifndef NOSPL
  313. #ifndef NOFRILLS
  314.     "getok",       XXGOK, 0,        /* GETOK (ask for Yes/No) */
  315. #endif /* NOFRILLS */
  316. #endif /* NOSPL */
  317. #ifndef NOSPL
  318.     "goto",        XXGOTO,0,        /* GOTO label in take file or macro */
  319. #endif /* NOSPL */
  320.     "hangup",      XXHAN, 0,        /* HANGUP the connection */
  321.     "help",       XXHLP, 0,        /* display HELP text */
  322. #ifndef NOSPL
  323.     "i",           XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  324.     "if",          XXIF,  0,         /* IF (condition) command */
  325.     "in",          XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  326.     "increment",   XXINC, 0,         /* Increment a numeric variable */
  327.     "input",       XXINP, 0,         /* INPUT text from comm device */
  328. #endif /* NOSPL */
  329. #ifndef NOHELP
  330.      "introduction", XXINT, 0,        /* Print introductory text */
  331. #endif /* NOHELP */
  332. #ifndef NOFRILLS
  333.     "l",           XXLOG, CM_INV|CM_ABR, /* Invisible synonym for log */
  334. #endif /* NOFRILLS */
  335.     "log",         XXLOG, 0,        /* Open a log file */
  336. #ifndef NOFRILLS
  337. #ifndef MAC
  338.     "ls",          XXDIR, CM_INV,    /* Invisible synonym for DIRECTORY */
  339. #endif /* MAC */
  340.     "mail",        XXMAI, 0,        /* Send a file as e-mail */
  341.     "man",         XXHLP, CM_INV,       /* Synonym for HELP */
  342. #endif /* NOFRILLS */
  343. #ifndef NOMSEND
  344.     "mget",        XXGET, CM_INV,    /* MGET = GET */
  345. #endif /* NOMSEND */
  346. #ifndef NOSPL
  347.     "mpause",      XXMSL, CM_INV,    /* Millisecond sleep */
  348. #endif /* NOSPL */
  349. #ifndef NOMSEND
  350.     "ms",          XXMSE, CM_INV|CM_ABR,
  351.     "msend",       XXMSE, 0,        /* Multiple SEND */
  352. #endif /* NOMSEND */
  353. #ifndef NOSPL
  354.     "msleep",      XXMSL, 0,        /* Millisecond sleep */
  355. #endif /* NOSPL */
  356. #ifndef NOMSEND
  357.     "mput",        XXMSE, CM_INV,    /* MPUT = MSEND */
  358. #endif /* NOMSEND */
  359. #ifndef NOFRILLS
  360.     "mv",          XXREN, CM_INV,    /* Synonym for rename */
  361. #endif /* NOFRILLS */
  362.     "news",        XXNEW, 0,        /* Display NEWS of new features */
  363. #ifndef NOSPL
  364.     "o",           XXOUT, CM_INV|CM_ABR, /* Invisible synonym for OUTPUT */
  365.     "open",        XXOPE, 0,        /* OPEN file for reading or writing */
  366.     "output",      XXOUT, 0,        /* OUTPUT text to comm device */
  367. #endif /* NOSPL */
  368. #ifdef SUNX25
  369.     "pad",         XXPAD, 0,            /* X.3 PAD commands */
  370. #endif /* SUNX25 */
  371. #ifndef NOSPL
  372.     "pause",       XXPAU, 0,        /* Sleep for specified interval */
  373. #ifdef TCPSOCKET
  374.     "ping",        XXPNG, 0,        /* PING (for TCP/IP) */
  375. #endif /* TCPSOCKET */
  376.     "pop",         XXEND, CM_INV,    /* Invisible synonym for END */
  377. #endif /* NOSPL */
  378. #ifndef NOFRILLS
  379.     "print",       XXPRI, 0,        /* PRINT a file locally */
  380. #ifndef NOPUSH
  381.     "pu",          XXSHE, CM_INV,    /* PU = PUSH */
  382.     "push",        XXSHE, 0,        /* PUSH command (like RUN, !) */
  383. #endif /* NOPUSH */
  384.     "put",       XXSEN, CM_INV,    /* PUT = SEND */
  385. #ifndef MAC
  386.     "pwd",         XXPWD, 0,            /* Print Working Directory */
  387. #endif /* MAC */
  388. #endif /* NOFRILLS */
  389.     "quit",       XXQUI, 0,        /* QUIT from program = EXIT */
  390.     "r",           XXREC, CM_INV,    /* Invisible synonym for RECEIVE */
  391. #ifndef NOSPL
  392.     "read",        XXREA, 0,            /* READ a line from a file */
  393. #endif /* NOSPL */
  394.     "receive",       XXREC, 0,        /* RECEIVE files */
  395. #ifndef NODIAL
  396.     "redial",      XXRED, 0,        /* REDIAL last DIAL number */
  397. #endif /* NODIAL */
  398. #ifndef NOSPL
  399.     "reinput",     XXREI, 0,            /* REINPUT (from INPUT buffer) */
  400. #endif /* NOSPL */
  401.     "remote",       XXREM, 0,        /* Send generic command to server */
  402. #ifndef NOFRILLS
  403.     "rename",      XXREN, 0,        /* RENAME a local file */
  404.     "replay",      XXTYP, CM_INV,    /* REPLAY (for now, just type) */
  405. #endif /* NOFRILLS */
  406. #ifndef NOSPL
  407.     "return",      XXRET, 0,        /* RETURN from a function */
  408. #endif /* NOSPL */
  409. #ifndef NOFRILLS
  410.     "rm",          XXDEL, CM_INV,    /* Invisible synonym for delete */
  411. #endif /* NOFRILLS */
  412. #ifndef NOPUSH
  413.     "run",         XXSHE, 0,        /* RUN a program or command */
  414. #endif /* NOPUSH */
  415.     "s",           XXSEN, CM_INV|CM_ABR, /* Invisible synonym for send */
  416. #ifndef NOSCRIPT
  417.     "script",       XXLOGI,0,        /* Execute a UUCP-style script */
  418. #endif /* NOSCRIPT */
  419.     "send",       XXSEN, 0,        /* Send (a) file(s) */
  420. #ifndef NOSERVER
  421.     "server",       XXSER, 0,        /* Be a SERVER */
  422. #endif /* NOSERVER */
  423.     "set",       XXSET, 0,        /* SET parameters */
  424. #ifndef NOSHOW
  425.     "show",        XXSHO, 0,        /* SHOW parameters */
  426. #endif /* NOSHOW */
  427. #ifndef NOSPL
  428. #ifndef NOFRILLS
  429.     "sleep",       XXPAU, CM_INV,    /* SLEEP for specified interval */
  430. #endif /* NOFRILLS */
  431. #endif /* NOSPL */
  432. #ifndef MAC
  433. #ifndef NOFRILLS
  434.     "sp",          XXSPA, CM_INV|CM_ABR,
  435.     "spa",         XXSPA, CM_INV|CM_ABR,
  436. #endif /* NOFRILLS */
  437.     "space",       XXSPA, 0,        /* Show available disk SPACE */
  438. #endif /* MAC */
  439. #ifndef NOFRILLS
  440. #ifndef NOPUSH
  441.     "spawn",       XXSHE, CM_INV,    /* Synonym for PUSH, RUN */
  442. #endif /* NOPUSH */
  443. #endif /* NOFRILLS */
  444.     "statistics",  XXSTA, 0,        /* Display file transfer stats */
  445. #ifndef NOSPL
  446.     "stop",        XXSTO, 0,        /* STOP all take files and macros */
  447. #endif /* NOSPL */
  448. #ifndef NOJC
  449.     "suspend",     XXSUS, 0,        /* SUSPEND C-Kermit (UNIX only) */
  450. #endif /* NOJC */
  451.     "take",       XXTAK, 0,        /* TAKE commands from a file */
  452. #ifndef NOFRILLS
  453. #ifdef TCPSOCKET
  454.     "telnet",      XXTEL, 0,        /* TELNET (TCP/IP only) */
  455. #endif /* TCPSOCKET */
  456. #ifdef DEBUG
  457.     "test",        XXTES, CM_INV,    /* (for testing) */
  458. #endif /* DEBUG */
  459. #endif /* NOFRILLS */
  460. #ifndef NOCSETS
  461.     "translate",   XXXLA, 0,        /* TRANSLATE local file char sets */
  462. #endif
  463. #ifndef NOXMIT
  464.     "transmit",    XXTRA, 0,        /* Send (upload) a file, no protocol */
  465. #endif /* NOXMIT */
  466. #ifndef NOFRILLS
  467.     "type",        XXTYP, 0,        /* Display a local file */
  468. #endif /* NOFRILLS */
  469.     "version",     XXVER, 0        /* VERSION-number display */
  470. #ifndef NOSPL
  471. ,   "wait",        XXWAI, 0        /* WAIT (like pause) */
  472. ,   "while",       XXWHI, 0        /* WHILE loop */
  473. #endif /* NOSPL */
  474. #ifndef MAC
  475. #ifndef NOFRILLS
  476. ,   "who",         XXWHO, 0        /* WHO's logged in? */
  477. #endif /* NOFRILLS */
  478. #endif /* MAC */
  479. #ifndef NOSPL
  480. ,   "write",       XXWRI, 0        /* WRITE to a file */
  481. ,   "xif",         XXIFX, 0        /* Extended IF command */
  482. #endif /* NOSPL */
  483. #ifndef NOCSETS
  484. ,   "xlate",       XXXLA, CM_INV    /* Synonym for TRANSLATE */
  485. #endif
  486. #ifndef NOXMIT
  487. ,   "xmit",        XXTRA, CM_INV    /* Synonym for TRANSMIT */
  488. #endif /* NOXMIT */
  489. ,   "z",           XXSUS, CM_INV    /* Synonym for SUSPEND */
  490. #ifndef NOSPL
  491. ,   "_assign",     XXASX, CM_INV    /* Used internally by FOR, etc */
  492. ,   "_define",     XXDFX, CM_INV    /* Used internally by FOR, etc */
  493. ,   "_getargs",    XXGTA, CM_INV        /* Used internally by FOR, etc */
  494. ,   "_putargs",    XXPTA, CM_INV        /* Used internally by FOR, etc */
  495. #endif /* NOSPL */
  496. };
  497. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab));
  498.  
  499. char toktab[] = {
  500. #ifndef NOPUSH
  501.     '!',                /* Shell escape */
  502. #endif /* NOPUSH */
  503.     '#',                /* Comment */
  504.     ';',                /* Comment */
  505. #ifndef NOSPL
  506.     ':',                /* Label */
  507. #endif /* NOSPL */
  508. #ifndef NOPUSH
  509.     '@',                /* DCL escape */
  510. #endif /* NOPUSH */
  511.     '\0'                /* End of this string */
  512. };
  513.  
  514. #ifndef NOSPL
  515. #ifndef NOFRILLS
  516. struct keytab yesno[] = {
  517.     "no",    0, 0,
  518.     "ok",    1, 0,
  519.     "yes",   1, 0
  520. };
  521. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  522. #endif /* NOFRILLS */
  523. #endif /* NOSPL */
  524.  
  525. /* Parameter keyword table */
  526.  
  527. struct keytab prmtab[] = {
  528.     "attributes",       XYATTR,  0,
  529.     "b",        XYBACK,  CM_INV|CM_ABR,
  530.     "ba",        XYBACK,  CM_INV|CM_ABR,
  531.     "background",       XYBACK,  0,
  532.     "baud",            XYSPEE,  CM_INV,
  533.     "block-check",      XYCHKT,  0,
  534. #ifdef DYNAMIC
  535.     "buffers",          XYBUF,   0,
  536. #endif /* DYNAMIC */
  537. #ifndef MAC
  538.     "carrier",          XYCARR,  0,
  539. #endif /* MAC */
  540. #ifndef NOSPL
  541.     "case",             XYCASE,  0,
  542. #endif /* NOSPL */
  543.     "command",          XYCMD,   0,
  544. #ifdef CK_SPEED
  545.     "control-character",XYQCTL,  0,
  546. #endif /* CK_SPEED */
  547. #ifndef NOSPL
  548.     "count",            XYCOUN,  0,
  549. #endif /* NOSPL */
  550.     "d",        XYDELA,  CM_INV|CM_ABR,
  551.     "de",        XYDELA,  CM_INV|CM_ABR,
  552.     "debug",            XYDEBU,  CM_INV,
  553. #ifdef VMS
  554.     "default",          XYDFLT,  0,
  555. #else
  556. #ifndef MAC
  557.     "default",          XYDFLT,  CM_INV,
  558. #endif /* MAC */
  559. #endif /* VMS */
  560.     "delay",            XYDELA,  0,
  561. #ifndef NODIAL
  562.     "dial",             XYDIAL,  0,
  563. #endif /* NODIAL */
  564.     "duplex",            XYDUPL,  0,
  565.     "escape-character", XYESC,   0,
  566.     "file",           XYFILE,  0,
  567.     "flow-control",     XYFLOW,  0,
  568.     "handshake",        XYHAND,  0,
  569. #ifdef NETCONN
  570.     "host",             XYHOST,  0,
  571. #endif /* NETCONN */
  572.     "incomplete",       XYIFD,   CM_INV,
  573. #ifndef NOSPL
  574.     "i",        XYINPU,  CM_INV|CM_ABR,
  575.     "in",        XYINPU,  CM_INV|CM_ABR,
  576.     "input",            XYINPU,  0,
  577. #ifndef MAC
  578. #ifndef NOSETKEY
  579.     "key",        XYKEY,   0,
  580. #endif /* NOSETKEY */
  581. #endif /* MAC */
  582. #endif /* NOSPL */
  583.     "l",                XYLINE,  CM_INV|CM_ABR,
  584. #ifndef NOCSETS
  585.     "language",         XYLANG,  0,
  586. #endif /* NOCSETS */
  587.     "line",             XYLINE,  0,
  588.     "local-echo",    XYLCLE,  CM_INV,
  589. #ifndef NOSPL
  590.     "macro",            XYMACR,  0,
  591. #endif /* NOSPL */
  592. #ifdef COMMENT
  593. #ifdef VMS
  594.     "messages",         XYMSGS,  0,
  595. #endif /* VMS */
  596. #endif /* COMMENT */
  597. #ifndef NODIAL
  598.     "modem-dialer",    XYMODM,     0,
  599. #endif
  600. #ifdef NETCONN
  601.     "network",          XYNET,   0,
  602. #endif /* NETCONN */
  603. #ifndef NOSPL
  604.     "output",           XYOUTP,  0,
  605. #endif /* NOSPL */
  606. #ifdef SUNX25
  607.     "pad",              XYPAD,   0,
  608. #endif /* SUNX25 */
  609.     "parity",            XYPARI,  0,
  610.     "port",             XYLINE,  CM_INV,
  611. #ifndef NOFRILLS
  612.     "prompt",            XYPROM,  0,
  613. #endif /* NOFRILLS */
  614.     "quiet",        XYQUIE,  0,
  615.     "receive",          XYRECV,  0,
  616.     "repeat",           XYREPT,  0,
  617.     "retry-limit",      XYRETR,  0,
  618. #ifndef NOSCRIPT
  619.     "script",        XYSCRI,  0,
  620. #endif /* NOSCRIPT */
  621.     "send",             XYSEND,  0,
  622. #ifndef NOSERVER
  623.     "server",           XYSERV,  0,
  624. #endif /* NOSERVER */
  625. #ifdef UNIX
  626.     "session-log",      XYSESS,  0,
  627. #endif /* UNIX */
  628.     "speed",            XYSPEE,  0,
  629. #ifndef NOJC
  630.     "suspend",          XYSUSP,  0,
  631. #endif /* NOJC */
  632.     "take",             XYTAKE,  0,
  633. #ifdef TNCODE
  634.     "telnet",           XYTEL,   0,
  635. #endif /* TNCODE */
  636.     "terminal",         XYTERM,  0,
  637.     "transfer",         XYXFER,  0,
  638. #ifndef NOXMIT
  639.     "transmit",         XYXMIT,  0,
  640. #endif /* NOXMIT */
  641. #ifndef NOCSETS
  642.     "unknown-char-set", XYUNCS,  0,
  643. #endif /* NOCSETS */
  644. #ifdef UNIX
  645.     "wildcard-expansion", XYWILD, 0,
  646. #endif /* UNIX */
  647.     "window-size",      XYWIND,  0
  648. #ifdef SUNX25
  649. ,   "x.25",             XYX25,   0,
  650.     "x25",              XYX25,   CM_INV
  651. #endif /* SUNX25 */
  652. #ifndef NOCSETS
  653. ,   "xfer",             XYXFER,  CM_INV
  654. #endif /* NOCSETS */
  655. #ifndef NOXMIT
  656. ,   "xmit",             XYXMIT,  CM_INV
  657. #endif /* NOXMIT */
  658. };
  659. int nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */
  660.  
  661. /* Table of networks */
  662. #ifdef NETCONN
  663. struct keytab netcmd[] = {
  664. #ifdef DECNET
  665.     "decnet",        NET_DEC,  0,
  666. #endif /* DECNET */
  667. #ifdef NPIPE
  668.     "named-pipe",    NET_PIPE, 0,
  669. #endif /* NPIPE */
  670. #ifdef TCPSOCKET
  671.     "tcp/ip",        NET_TCPB, 0
  672. #endif /* TCPSOCKET */
  673. #ifdef SUNX25
  674. ,   "x",            NET_SX25, CM_INV|CM_ABR,
  675.     "x.25",         NET_SX25, 0,
  676.     "x25",          NET_SX25, CM_INV
  677. #endif /* SUNX25 */
  678. };
  679. int nnets = (sizeof(netcmd) / sizeof(struct keytab)); /* How many networks */
  680. #endif /* NETCONN */
  681.  
  682. /* Remote Command Table */
  683.  
  684. struct keytab remcmd[] = {
  685.     "cd",        XZCWD, 0,
  686.     "cwd",       XZCWD, CM_INV,
  687.     "delete",    XZDEL, 0,
  688.     "directory", XZDIR, 0,
  689.     "help",      XZHLP, 0,
  690. #ifndef NOPUSH
  691.     "host",      XZHOS, 0,
  692. #endif /* NOPUSH */
  693. #ifndef NOFRILLS
  694.     "kermit",    XZKER, 0,
  695.     "login",     XZLGI, 0,
  696.     "logout",    XZLGO, 0,
  697.     "print",     XZPRI, 0,
  698. #endif /* NOFRILLS */
  699.     "set",       XZSET, 0,
  700.     "space",     XZSPA, 0
  701. #ifndef NOFRILLS
  702. ,   "type",      XZTYP, 0,
  703.     "who",       XZWHO, 0
  704. #endif /* NOFRILLS */
  705. };
  706. int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
  707.  
  708. struct keytab logtab[] = {
  709. #ifdef DEBUG
  710.     "debugging",    LOGD, 0,
  711. #endif /* DEBUG */
  712.     "packets",        LOGP, 0,
  713.     "session",      LOGS, 0
  714. #ifdef TLOG
  715. ,   "transactions", LOGT, 0
  716. #endif /* TLOG */
  717. };
  718. int nlog = (sizeof(logtab) / sizeof(struct keytab));
  719.  
  720. struct keytab writab[] = {
  721. #ifndef NOSPL
  722.     "append-file",     LOGW, CM_INV,
  723. #endif /* NOSPL */
  724.     "debug-log",       LOGD, 0,
  725.     "error",           LOGE, 0,
  726. #ifndef NOSPL
  727.     "file",            LOGW, 0,
  728. #endif /* NOSPL */
  729.     "packet-log",      LOGP, 0,
  730.     "screen",          LOGX, 0,
  731.     "session-log",     LOGS, 0,
  732.     "sys$output",      LOGX, CM_INV,
  733.     "transaction-log", LOGT, 0
  734. };
  735. int nwri = (sizeof(writab) / sizeof(struct keytab));
  736.  
  737. #define CLR_DEV  1
  738. #define CLR_INP  2
  739.  
  740. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  741. #ifndef NOSPL
  742.     "both",          CLR_DEV|CLR_INP, 0,
  743. #endif /* NOSPL */
  744.     "device-buffer", CLR_DEV,         0,
  745. #ifndef NOSPL
  746.     "input-buffer",  CLR_INP,         0
  747. #endif /* NOSPL */
  748. };
  749. int nclear = (sizeof(clrtab) / sizeof(struct keytab));
  750.  
  751. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  752. #ifndef NOSPL
  753.     "append-file",     LOGW, CM_INV,
  754. #endif /* NOSPL */
  755. #ifdef DEBUG
  756.     "debug-log",       LOGD, 0,
  757. #endif /* DEBUG */
  758.     "packet-log",      LOGP, 0,
  759. #ifndef NOSPL
  760.     "read-file",       LOGR, 0,
  761. #endif /* NOSPL */
  762.     "session-log",     LOGS, 0
  763. #ifdef TLOG
  764. ,   "transaction-log", LOGT, 0
  765. #endif /* TLOG */
  766. #ifndef NOSPL
  767. ,   "write-file",      LOGW, 0
  768. #endif /* NOSPL */
  769. };
  770. int ncls = (sizeof(clstab) / sizeof(struct keytab));
  771.  
  772. /* SHOW command arguments */
  773.  
  774. struct keytab shotab[] = {
  775. #ifndef NOSPL
  776.     "arguments", SHARG, 0,
  777.     "arrays", SHARR, 0,
  778. #endif /* NOSPL */
  779.     "attributes", SHATT, 0,
  780.     "character-sets", SHCSE, 0,
  781.     "communications", SHCOM, 0,
  782. #ifdef CK_SPEED
  783.     "control-prefixing", SHCTL, 0,
  784. #endif /* CK_SPEED */
  785. #ifndef NOSPL
  786.     "count", SHCOU, 0,
  787. #endif /* NOSPL */
  788. #ifdef VMS
  789.     "default", SHDFLT, 0,
  790. #else
  791.     "default", SHDFLT, CM_INV,
  792. #endif /* VMS */
  793. #ifndef NODIAL
  794.     "dial", SHDIA, 0,
  795. #endif /* NODIAL */
  796.     "escape", SHESC, 0,
  797.     "features", SHFEA, 0,
  798.     "file", SHFIL, 0,
  799. #ifndef NOSPL
  800.     "functions", SHFUN, 0,
  801.     "globals", SHVAR, 0,
  802. #endif /* NOSPL */
  803. #ifndef NOSETKEY
  804.     "key", SHKEY, 0,
  805. #endif /* NOSETKEY */
  806. #ifdef VMS
  807.     "labeled-file-info", SHLBL, 0,
  808. #endif /* VMS */
  809. #ifndef NOCSETS
  810.     "languages", SHLNG, 0,
  811. #endif /* NOCSETS */
  812. #ifndef NOSPL
  813.     "macros", SHMAC, 0,
  814. #endif /* NOSPL */
  815.     "modem-signals", SHMOD, 0,
  816.     "network", SHNET, 0,
  817. #ifdef SUNX25
  818.     "pad", SHPAD, 0,
  819. #endif /* SUNX25 */
  820.     "parameters", SHPAR, CM_INV,
  821.     "protocol", SHPRO, 0,
  822. #ifndef NOSPL
  823.     "scripts", SHSCR, 0,
  824. #endif /* NOSPL */
  825. #ifndef NOSERVER
  826.     "server", SHSER, 0,
  827. #endif /* NOSERVER */
  828.     "status", SHSTA, 0,
  829. #ifdef MAC
  830.     "stack", SHSTK, 0,            /* debugging */
  831. #endif /* MAC */
  832.     "terminal", SHTER, 0
  833. #ifndef NOXMIT
  834. ,   "transmit", SHXMI, 0
  835. #endif /* NOXMIT */
  836. #ifndef NOSPL
  837. ,   "variables", SHBUI, 0
  838. #endif /* NOSPL */
  839. #ifndef NOFRILLS
  840. ,   "versions", SHVER, 0
  841. #endif /* NOFRILLS */
  842. #ifndef NOXMIT
  843. ,   "xmit", SHXMI, CM_INV
  844. #endif /* NOXMIT */
  845. };
  846. int nsho = (sizeof(shotab) / sizeof(struct keytab));
  847.  
  848. #ifdef SUNX25
  849. struct keytab padtab[] = {              /* PAD commands */
  850.     "clear",      XYPADL, 0,
  851.     "interrupt",  XYPADI, 0,
  852.     "reset",      XYPADR, 0,
  853.     "status",     XYPADS, 0
  854. };
  855. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  856. #endif /* SUNX25 */
  857.  
  858. struct keytab enatab[] = {        /* ENABLE commands */
  859.     "all",        EN_ALL,  0,
  860. #ifndef datageneral
  861.     "bye",        EN_BYE,  0,
  862. #endif /* datageneral */
  863.     "cd",         EN_CWD,  0,
  864.     "cwd",        EN_CWD,  CM_INV,
  865.     "delete",     EN_DEL,  0,
  866.     "directory",  EN_DIR,  0,
  867.     "finish",     EN_FIN,  0,
  868.     "get",        EN_GET,  0,
  869.     "host",       EN_HOS,  0,
  870.     "send",       EN_SEN,  0,
  871.     "set",        EN_SET,  0,
  872.     "space",      EN_SPA,  0,
  873.     "type",       EN_TYP,  0,
  874.     "who",        EN_WHO,  0
  875. };
  876. int nena = (sizeof(enatab) / sizeof(struct keytab));
  877.  
  878. #ifndef NOSPL
  879. #ifdef COMMENT
  880. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  881.     NULL, NULL, 0
  882. };
  883. #else
  884. struct mtab *mactab;            /* Dynamically allocated macro table */
  885. #endif /* COMMENT */
  886. int nmac = 0;
  887.  
  888. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  889. #endif /* NOSPL */
  890.  
  891. /* Forward declarations of functions */
  892.  
  893. _PROTOTYP (int doask,   ( int  ) );
  894. _PROTOTYP (int dodef,   ( int  ) );
  895. _PROTOTYP (int dodel,   ( void ) );
  896. _PROTOTYP (int dodial,  ( int  ) );
  897. _PROTOTYP (int dodir,   ( void ) );
  898. _PROTOTYP (int doelse,  ( void ) );
  899. _PROTOTYP (int dofor,   ( void ) );
  900. _PROTOTYP (int dogta,   ( int  ) );
  901. _PROTOTYP (int doincr,  ( int  ) );
  902. _PROTOTYP (int dopaus,  ( int  ) );
  903. _PROTOTYP (int doping,  ( void ) );
  904. _PROTOTYP (int dorenam, ( void ) );
  905.  
  906. #ifdef TCPSOCKET
  907. int
  908. doping() {
  909.     char *p;
  910.     int x;
  911.  
  912.     if (network)            /* If we have a current connection */
  913.       strcpy(line,ttname);        /* get the host name */
  914.     else *line = '\0';            /* as default host to be pinged. */
  915.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  916.       if (*p == ':') { *p = '\0'; break; }
  917.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  918.       return(x);
  919. /* Construct PING command */
  920. #ifdef VMS
  921. #ifdef MULTINET                /* TGV MultiNet */
  922.     sprintf(line,"multinet ping %s /num=1",s);
  923. #else
  924.     sprintf(line,"ping %s 56 1",s);    /* Other VMS TCP/IP's */
  925. #endif /* MULTINET */
  926. #else                    /* Not VMS */
  927.     sprintf(line,"ping %s",s);
  928. #endif /* VMS */
  929.     conres();                /* Make console normal  */
  930. #ifdef DEC_TCPIP
  931.     printf("\n");            /* Prevent prompt-stomping */
  932. #endif /* DEC_TCPIP */
  933.     x = zshcmd(line);
  934.     concb((char)escape);
  935.     return(success = 1);        /* We don't know the status */
  936. }
  937. #endif /* TCPSOCKET */
  938.  
  939. /*  D O C M D  --  Do a command  */
  940.  
  941. /*
  942.  Returns:
  943.    -2: user typed an illegal command
  944.    -1: reparse needed
  945.     0: parse was successful (even tho command may have failed).
  946. */ 
  947. int
  948. docmd(cx) int cx; {
  949.  
  950.     debug(F101,"docmd entry, cx","",cx);
  951.  
  952. /*
  953.   Massive switch() broken up into many smaller ones, for the benefit of
  954.   compilers that run out of space when trying to handle large switch
  955.   statements.
  956. */
  957.     switch (cx) {
  958.       case -4:            /* EOF */
  959. #ifdef OSK
  960.     if (msgflg)  printf("\n");
  961. #else
  962.     if (msgflg)  printf("\r\n");
  963. #endif /* OSK */
  964.       doexit(GOOD_EXIT,xitsta);
  965.       case -3:                /* Null command */
  966.     return(0);
  967.       case -9:                /* Like -2, but errmsg already done */
  968.       case -1:                /* Reparse needed */
  969.     return(cx);
  970.       case -6:                /* Special */
  971.       case -2:                /* Error, maybe */
  972. #ifndef NOSPL
  973. /*
  974.   Maybe they typed a macro name.  Let's look it up and see.
  975. */
  976.     if (cx == -6)            /* If they typed CR */
  977.       strcat(cmdbuf,"\015");    /*  add it back to command buffer. */
  978.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  979.       ifcmd[cmdlvl]--;
  980.     repars = 1;            /* Force reparse */
  981.     cmres();
  982.     cx = XXDO;            /* Try DO command */
  983. #else
  984.     return(cx);
  985. #endif /* NOSPL */
  986.       default:
  987.     break;
  988.     }
  989.  
  990. #ifndef NOSPL
  991. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  992.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  993.     int x;
  994.     debug(F101,"docmd XXGTA","",XXGTA);
  995.     debug(F101,"docmd cx","",cx);
  996.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  997.     x = dogta(cx);
  998.     debug(F101,"docmd dogta returns","",x);
  999.     debug(F101,"docmd dogta maclvl","",maclvl);
  1000.     return(x);
  1001.     }
  1002. #endif /* NOSPL */
  1003.  
  1004. #ifndef NOSPL
  1005. /* ASK, ASKQ, READ */
  1006.     if (cx == XXASK || cx == XXASKQ || cx == XXREA) {
  1007.     return(doask(cx));
  1008.     }
  1009. #endif /* NOSPL */
  1010.  
  1011. #ifndef NOFRILLS
  1012.     if (cx == XXBUG) {            /* BUG */
  1013.     if ((x = cmcfm()) < 0) return(x);
  1014.     return(dobug());
  1015.     }
  1016. #endif /* NOFRILLS */
  1017.  
  1018.     if (cx == XXBYE) {            /* BYE */
  1019.     if ((x = cmcfm()) < 0) return(x);
  1020.     sstate = setgen('L',"","","");
  1021.     if (local) ttflui();        /* If local, flush tty input buffer */
  1022.     return(0);
  1023.     } 
  1024.  
  1025. #ifndef NOFRILLS
  1026.     if (cx == XXCLE) {            /* CLEAR */
  1027.     if ((x = cmkey(clrtab,nclear,"buffer(s) to clear",
  1028. #ifdef NOSPL
  1029.           "device-buffer"
  1030. #else
  1031.           "both"
  1032. #endif /* NOSPL */
  1033.           ,xxstring)) < 0) return(x);
  1034.     if ((y = cmcfm()) < 0) return(y);
  1035.  
  1036.     /* Clear device input buffer if requested */
  1037.     y = (x & CLR_DEV) ? ttflui() : 0;
  1038. #ifndef NOSPL
  1039.     /* Clear INPUT command buffer if requested */
  1040.     if (x & CLR_INP) {
  1041.         for (x = 0; x < INPBUFSIZ; x++)
  1042.           inpbuf[x] = 0;
  1043.         inpbp = inpbuf;
  1044.     }
  1045. #endif /* NOSPL */
  1046.     return(success = (y == 0));
  1047.     }
  1048. #endif /* NOFRILLS */
  1049.  
  1050.     if (cx == XXCOM) {            /* COMMENT */
  1051.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  1052.       return(x);
  1053.     /* Don't change SUCCESS flag for this one */
  1054.     return(0);
  1055.     } 
  1056.  
  1057.     if (cx == XXCON) {            /* CONNECT */
  1058.     if ((x = cmcfm()) < 0)
  1059.       return(x);
  1060.     return(success = doconect());
  1061.     }
  1062.  
  1063.     if (cx == XXCWD)            /* CWD */
  1064.       return(success = docd());
  1065.  
  1066.     if (cx == XXCHK)            /* CHECK */
  1067.       return(success = dochk());
  1068.  
  1069.     if (cx == XXCLO) {            /* CLOSE */
  1070.     x = cmkey(clstab,ncls,"Which log or file to close","",xxstring);
  1071.     if (x == -3) {
  1072.         printf("?You must say which file or log\n");
  1073.         return(-9);
  1074.     }
  1075.     if (x < 0) return(x);
  1076.     if ((y = cmcfm()) < 0) return(y);
  1077.     y = doclslog(x);
  1078.     success = (y == 1);
  1079.     return(success);
  1080.     }
  1081.  
  1082. #ifndef NOSPL
  1083.     if (cx == XXDEC || cx == XXINC)    /* DECREMENT, INCREMENT */
  1084.       return(doincr(cx));
  1085. #endif /* NOSPL */
  1086.  
  1087. #ifndef NOSPL
  1088.     if (cx == XXDEF || cx == XXASS || cx == XXASX || cx == XXDFX)
  1089.       return(dodef(cx));        /* DEFINE, ASSIGN */
  1090. #endif /* NOSPL */
  1091.  
  1092. #ifndef NOSPL    
  1093.     if (cx == XXDCL) {            /* DECLARE an array */
  1094.     if ((y = cmfld("Array name","",&s,NULL)) < 0) {
  1095.         if (y == -3) {
  1096.         printf("?Array name required\n");
  1097.         return(-9);
  1098.         } else return(y);
  1099.     }
  1100.     if ((y = arraynam(s,&x,&z)) < 0) return(y);
  1101.     if ((y = cmcfm()) < 0) return(y);
  1102.     if (dclarray((char)x,z) < 0) {
  1103.         printf("?Declare failed\n");
  1104.         return(success = 0);
  1105.     }
  1106.     return(success = 1);
  1107.     }
  1108. #endif /* NOSPL */
  1109.  
  1110.  
  1111. #ifndef NODIAL
  1112.     if (cx == XXRED || cx == XXDIAL)    /* DIAL or REDIAL */
  1113.       return(dodial(cx));
  1114. #endif /* NODIAL */
  1115.  
  1116. #ifndef NOFRILLS
  1117.     if (cx == XXDEL)            /* DELETE */
  1118.       return(dodel());
  1119. #endif /* NOFRILLS */
  1120.  
  1121. #ifndef MAC
  1122.     if (cx == XXDIR)            /* DIRECTORY */
  1123.       return(dodir());
  1124. #endif /* MAC */
  1125.  
  1126. #ifndef NOSPL
  1127.     if (cx == XXELS)            /* ELSE */
  1128.       return(doelse());
  1129. #endif /* NOSPL */
  1130.  
  1131. #ifndef NOFRILLS
  1132.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  1133.     s = (cx == XXENA) ?
  1134.       "Server function to enable" :
  1135.         "Server function to disable";
  1136.  
  1137.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  1138.         if (x == -3) {
  1139.         printf("?Name of server function required\n");
  1140.         return(-9);
  1141.         } else return(x);
  1142.     }
  1143.     if ((y = cmcfm()) < 0) return(y);
  1144.     return(doenable(cx,x));
  1145.     }
  1146. #endif /* NOFRILLS */
  1147.  
  1148. #ifndef NOSPL
  1149.     if (cx == XXRET) {            /* RETURN */
  1150.     if (cmdlvl == 0) {        /* At top level, nothing happens... */
  1151.         if ((x = cmcfm()) < 0)
  1152.           return(x);
  1153.         return(success = 1);
  1154.     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */
  1155.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1156.           return(x);        /* Allow trailing text, but ignore. */
  1157.         if ((x = cmcfm()) < 0)
  1158.           return(x);
  1159.         popclvl();            /* pop command level */
  1160.         return(success = 1);    /* always succeeds */
  1161.     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */  
  1162.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1163.           return(x);
  1164.         return(doreturn(s));    /* Trailing text is return value. */
  1165.     } else return(-2);
  1166.     }
  1167. #endif /* NOSPL */
  1168.  
  1169. #ifndef NOSPL
  1170.     if (cx == XXDO) {            /* DO (a macro) */
  1171.     if (nmac == 0) {
  1172.         printf("\n?No macros defined\n");
  1173.         return(-2);
  1174.     }
  1175.     for (y = 0; y < nmac; y++) {    /* copy the macro table */
  1176.         mackey[y].kwd = mactab[y].kwd; /* into a regular keyword table */
  1177.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  1178.         mackey[y].flgs = mactab[y].flgs;
  1179.     }
  1180.     /* parse name as keyword */
  1181.     if ((x = cmkey(mackey,nmac,"macro","",xxstring)) < 0) {
  1182.         if (x == -3) {
  1183.         printf("?Macro name required\n");
  1184.         return(-9);
  1185.         } else return(x);
  1186.     }
  1187.     if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  1188.       return(y);            /* get args */
  1189.     return(dodo(x,s) < 1 ? (success = 0) : 1);
  1190.     }
  1191. #endif /* NOSPL */
  1192.  
  1193.     if (cx == XXECH || cx == XXAPC) {    /* ECHO or APC */
  1194.     if ((x = cmtxt((cx == XXECH) ?
  1195.                "Text to be echoed" :
  1196.                "Application Program Command text",
  1197.                "",&s,xxstring)) < 0)
  1198.       return(x);
  1199.     if (*s == '{') {        /* Strip enclosing braces */
  1200.         x = (int)strlen(s);
  1201.         if (s[x-1] == '}') {
  1202.         s[x-1] = NUL;
  1203.         s++;
  1204.         }
  1205.     }
  1206.     if (cx == XXAPC) {        /* APC */
  1207.         printf("%c_%s%c\\",ESC,s,ESC);
  1208. #ifdef UNIX
  1209. #ifdef NOSETBUF
  1210.         fflush(stdout);
  1211. #endif /* NOSETBUF */
  1212. #endif /* UNIX */
  1213.     } else {            /* ECHO */
  1214.         printf("%s\n",s);
  1215.     }
  1216.     return(1);            /* Always succeeds */
  1217.     }
  1218.  
  1219. #ifndef NOSPL
  1220.     if (cx == XXOPE)            /* OPEN */
  1221.       return(doopen());
  1222. #endif /* NOSPL */
  1223.  
  1224. #ifndef NOSPL
  1225.     if (cx == XXOUT) {            /* OUTPUT */
  1226.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  1227.       return(x);
  1228.     debug(F110,"OUTPUT 1",s,0);
  1229.     if (*s == '{') {        /* Strip enclosing braces, */
  1230.         x = (int)strlen(s);        /* if any. */
  1231.         if (s[x-1] == '}') {
  1232.         s[x-1] = NUL;
  1233.         s++;
  1234.         }
  1235.     }
  1236.     debug(F110,"OUTPUT 2",s,0);
  1237.     for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \B, \L to \\B, \\L */
  1238.         if (x > 0 &&
  1239.         (s[x] == 'B' || s[x] == 'b' || s[x] == 'L' || s[x] == 'l'))
  1240.           if ((x == 1 && s[x-1] == CMDQ) ||
  1241.           (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ))
  1242.         line[y++] = CMDQ;
  1243.         line[y] = s[x];
  1244.     }
  1245.     line[y++] = '\0';        /* Now expand variables, etc. */
  1246.     debug(F110,"OUTPUT 3",line,0);
  1247.     s = line+y+1;
  1248.     x = LINBUFSIZ - strlen(line) - 1;
  1249.     debug(F101,"OUTPUT size","",x);
  1250.     if (xxstring(line,&s,&x) < 0)
  1251.       return(success = 0);
  1252.     s = line+y+1;
  1253.     debug(F110,"OUTPUT 4",s,0);
  1254.     return(success = dooutput(s));
  1255.     }
  1256. #endif /* NOSPL */
  1257.  
  1258. #ifdef SUNX25
  1259.     if (cx == XXPAD) {            /* PAD commands */
  1260.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  1261.     if (x == -3) {
  1262.         printf("?You must specify a PAD command to execute\n");
  1263.         return(-2);
  1264.     }
  1265.     if (x < 0) return(x);
  1266.     
  1267.     switch (x) {
  1268.       case XYPADL: 
  1269.         if (x25stat() < 0)
  1270.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1271.         else {
  1272.         x25clear();
  1273.         initpad();
  1274.         }
  1275.         break;
  1276.       case XYPADS:
  1277.         if (x25stat() < 0)
  1278.           printf("Not connected\r\n");
  1279.         else {
  1280.         extern int linkid, lcn;
  1281.         conol("Connected thru ");
  1282.         conol(ttname);
  1283.         printf(", Link id %d, Logical channel number %d\r\n",
  1284.                linkid,lcn);
  1285.         }
  1286.         break;
  1287.       case XYPADR:
  1288.         if (x25stat() < 0)
  1289.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1290.         else
  1291.           x25reset(0,0);
  1292.         break;
  1293.       case XYPADI:
  1294.         if (x25stat() < 0)
  1295.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1296.         else 
  1297.           x25intr(0);
  1298.     }
  1299.     return(0);
  1300. }
  1301. #endif /* SUNX25 */
  1302.  
  1303. #ifndef NOSPL
  1304.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  1305.       return(dopaus(cx));
  1306. #endif /* NOSPL */
  1307.  
  1308. #ifndef NOFRILLS
  1309.     if (cx == XXPRI) {
  1310.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  1311.         if (x == -3) {
  1312.         printf("?A file specification is required\n");
  1313.         return(-9);
  1314.         } else return(x);
  1315.     }
  1316.     if (y != 0) {
  1317.         printf("?Wildcards not allowed\n");
  1318.         return(-9);
  1319.     }
  1320.     strcpy(line,s);
  1321.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  1322.                xxstring)) < 0) return(x);
  1323.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  1324.     }
  1325.  
  1326. #ifdef TCPSOCKET
  1327.     if (cx == XXPNG)             /* PING an IP host */
  1328.       return(doping());
  1329. #endif /* TCPSOCKET */
  1330.  
  1331. #ifndef MAC
  1332.     if (cx == XXPWD) {            /* PWD */
  1333.     if ((x = cmcfm()) < 0) return(x);
  1334.     xsystem(PWDCMD);
  1335.     return(success = 1);        /* blind faith */
  1336.     }
  1337. #endif /* MAC */
  1338. #endif /* NOFRILLS */
  1339.  
  1340.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  1341.     if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) {
  1342.         if (y == -3)
  1343.           x = xitsta;
  1344.         else return(y);
  1345.     }
  1346.     if ((y = cmcfm()) < 0) return(y);
  1347. #ifdef VMS
  1348.     doexit(GOOD_EXIT,x);
  1349. #else
  1350. #ifdef OSK
  1351. /* Returning any codes here makes the OS-9 shell print an error message. */
  1352.     doexit(GOOD_EXIT,-1);
  1353. #else
  1354. #ifdef datageneral
  1355.         doexit(GOOD_EXIT,x);
  1356. #else
  1357.     doexit(x,-1);
  1358. #endif /* datageneral */
  1359. #endif /* OSK */
  1360. #endif /* VMS */
  1361.     }
  1362.  
  1363. #ifndef NOFRILLS
  1364.     if (cx == XXERR) {            /* ERROR */
  1365.     if ((x = cmcfm()) < 0) return(x);
  1366.     ttflui();
  1367.     sstate = 'a';
  1368.     return(0);
  1369.     }
  1370. #endif /* NOFRILLS */
  1371.  
  1372.     if (cx == XXFIN) {            /* FINISH */
  1373.     if ((x = cmcfm()) < 0) return(x);
  1374.     sstate = setgen('F',"","","");
  1375.     if (local) ttflui();        /* If local, flush tty input buffer */
  1376.     return(0);
  1377.     }
  1378.  
  1379. #ifndef NOSPL
  1380.     if (cx == XXFOR)            /* FOR loop */
  1381.       return(dofor());
  1382. #endif /* NOSPL */
  1383.  
  1384.     if (cx == XXGET) {            /* GET */
  1385.     x = cmtxt("Name of remote file(s), or carriage return","",&cmarg,
  1386.           xxstring);
  1387. #ifndef NOFRILLS
  1388.     if ((x == -2) || (x == -1)) return(x);
  1389. #else
  1390.     if (x < 0) return(x);
  1391. #endif /* NOFRILLS */
  1392.     if (*cmarg == '{') {        /* Strip any enclosing braces */
  1393.         x = (int)strlen(cmarg);    /* This allows preservation of */
  1394.         if (cmarg[x-1] == '}') {    /* leading and/or trailing */
  1395.         cmarg[x-1] = NUL;    /* spaces. */
  1396.         cmarg++;
  1397.         }
  1398.     }
  1399.     x = doget();
  1400. #ifdef MAC
  1401.     if (sstate == 'r')
  1402.         scrcreate();
  1403. #endif /* MAC */
  1404.     return(x);
  1405.     }
  1406.  
  1407. #ifndef NOSPL
  1408. #ifndef NOFRILLS
  1409.     if (cx == XXGOK) {            /* GETOK */
  1410.     return(success = doask(cx));
  1411.     }
  1412. #endif /* NOFRILLS */
  1413. #endif /* NOSPL */
  1414.  
  1415.     if (cx == XXHLP) {            /* HELP */
  1416. #ifdef NOHELP
  1417.     return(dohlp(XXHLP));        
  1418. #else
  1419.     x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring);
  1420.     debug(F101,"HELP command x","",x);
  1421.     if (x == -5) {
  1422.         y = chktok(toktab);
  1423.         debug(F101,"top-level cmkey token","",y);
  1424.         ungword();
  1425.         switch (y) {
  1426. #ifndef NOPUSH
  1427.           case '!': x = XXSHE; break;
  1428. #endif /* NOPUSH */
  1429.           case '#': x = XXCOM; break;
  1430.           case ';': x = XXCOM; break;
  1431. #ifndef NOSPL
  1432.           case ':': x = XXLBL; break;
  1433. #endif /* NOSPL */
  1434.           case '&': x = XXECH; break;
  1435.           default:
  1436.         printf("\n?Invalid - %s\n",cmdbuf);
  1437.         x = -2;
  1438.         }
  1439.     }
  1440.     return(dohlp(x));
  1441. #endif /* NOHELP */
  1442.     }
  1443.  
  1444. #ifndef NOHELP
  1445.     if (cx == XXINT)            /* INTRO */
  1446.       return(hmsga(introtxt));
  1447.     if (cx == XXNEW)            /* NEWS */
  1448.       return(hmsga(newstxt));
  1449. #endif /* NOHELP */
  1450.  
  1451.     if (cx == XXHAN) {            /* HANGUP */
  1452.     if ((x = cmcfm()) < 0) return(x);
  1453. #ifndef NODIAL
  1454.     if ((x = mdmhup()) < 1)
  1455. #endif /* NODIAL */
  1456.       x = (tthang() > -1);
  1457.     return(success = x);
  1458.     }
  1459.  
  1460. #ifndef NOSPL
  1461.     if (cx == XXGOTO) {            /* GOTO */
  1462. /* Note, here we don't set SUCCESS/FAILURE flag */
  1463.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  1464.         if (y == -3) {
  1465.         printf("?Label name required\n");
  1466.         return(-9);
  1467.         } else return(y);
  1468.     }
  1469.     strncpy(lblbuf,s,LBLSIZ);
  1470.     if ((x = cmcfm()) < 0) return(x);
  1471.     s = lblbuf;
  1472.     return(dogoto(s));
  1473.     }
  1474. #endif /* NOSPL */
  1475.  
  1476. #ifndef NOSPL
  1477. /* IF, Extended IF, WHILE */
  1478.     if (cx == XXIF || cx == XXIFX || cx == XXWHI) {
  1479.     return(doif(cx));
  1480.     }
  1481. #endif /* NOSPL */
  1482.  
  1483. #ifndef NOSPL
  1484.     if (cx == XXINP || cx == XXREI) {    /* INPUT and REINPUT */
  1485.     sprintf(tmpbuf,"%d",indef);
  1486.     y = cmnum("seconds to wait for input",(char *)tmpbuf,10,&x,xxstring);
  1487.     if (y < 0) {
  1488.         return(y);
  1489.     }
  1490.     if (x <= 0) x = 1;
  1491.     if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  1492.       return(y);
  1493. #ifdef COMMENT
  1494. /*
  1495.   Now it's ok -- null argument means wait for any character.
  1496. */
  1497.     if (*s == '\0') {
  1498.         printf("?Text required\n");
  1499.         return(-9);
  1500.     }
  1501. #endif /* COMMENT */
  1502.     if (*s == '{') {
  1503.         y = (int)strlen(s);
  1504.         if (s[y-1] == '}') {
  1505.         s[y-1] = NUL;
  1506.         s++;
  1507.         }
  1508.     }
  1509.     if (cx == XXINP) {        /* INPUT */
  1510.         debug(F110,"calling doinput",s,0);
  1511.         success = doinput(x,s);    /* Go try to input the search string */
  1512.     } else {            /* REINPUT */
  1513.         debug(F110,"xxrei line",s,0);
  1514.         success = doreinp(x,s);
  1515.     }
  1516.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  1517.         popclvl();            /* If so, pop command level. */
  1518.         if (pflag && cmdlvl == 0) {
  1519.         if (cx == XXINP) printf("?Input timed out\n");
  1520.         if (cx == XXREI) printf("?Reinput failed\n");
  1521.         }
  1522.     }
  1523.     return(success);        /* Return do(re)input's return code */
  1524.     }
  1525. #endif /* NOSPL */
  1526.  
  1527. #ifndef NOSPL
  1528.     if (cx == XXLBL) {            /* LABEL */
  1529.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  1530.         if (x == -3) {
  1531.         printf("?Label name required\n");
  1532.         return(-9);
  1533.         } else return(x);
  1534.     }
  1535.     if ((x = cmcfm()) < 0) return(x);
  1536.     return(0);
  1537.     }
  1538. #endif /* NOSPL */
  1539.  
  1540.     if (cx == XXLOG) {            /* LOG */
  1541.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  1542.     if (x == -3) {
  1543.         printf("?Type of log required\n");
  1544.         return(-9);
  1545.     }
  1546.     if (x < 0) return(x);
  1547.     x = dolog(x);
  1548.     if (x < 0)
  1549.       return(x);
  1550.     else
  1551.       return(success = x);
  1552.     }
  1553.  
  1554. #ifndef NOSCRIPT
  1555.     if (cx == XXLOGI) {            /* UUCP-style script */
  1556.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  1557.       return(x);
  1558. #ifdef VMS
  1559.     conres();            /* For Ctrl-C to work... */
  1560. #endif /* VMS */
  1561.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  1562.     }
  1563. #endif /* NOSCRIPT */
  1564.  
  1565.     if (cx == XXREC) {            /* RECEIVE */
  1566.     cmarg2 = "";
  1567.     x = cmofi("Name under which to store the file, or CR","",&s,
  1568.           xxstring);
  1569.     if ((x == -1) || (x == -2)) return(x);
  1570.     if ((x = cmcfm()) < 0) return(x);
  1571.     strcpy(line,s);
  1572.     cmarg2 = line;
  1573.     debug(F111,"cmofi cmarg2",cmarg2,x);
  1574.     sstate = 'v';
  1575. #ifdef MAC
  1576.     scrcreate();
  1577. #endif /* MAC */
  1578.     if (local) displa = 1;
  1579.     return(0);
  1580.     }
  1581.  
  1582.     if (cx == XXREM) {            /* REMOTE */
  1583.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  1584.     if (x == -3) {
  1585.         printf("?You must specify a command for the remote server\n");
  1586.         return(-9);
  1587.     }
  1588.     return(dormt(x));
  1589.     }
  1590.  
  1591. #ifndef NOFRILLS
  1592.     if (cx == XXREN)            /* RENAME */
  1593.       return(dorenam());
  1594. #endif /* NOFRILLS */
  1595.  
  1596.     if (cx == XXSEN || cx == XXMAI) {    /* SEND, MAIL */
  1597.     cmarg = cmarg2 = "";
  1598.     if ((x = cmifi("File(s) to send","",&s,&y,xxstring)) < 0) {
  1599.         if (x == -3) {
  1600.         printf("?A file specification is required\n");
  1601.         return(-9);
  1602.         } else return(x);
  1603.     }
  1604.     nfils = -1;            /* Files come from internal list. */
  1605.     strcpy(line,s);            /* Save copy of string just parsed. */
  1606.     strncpy(fspec,s,FSPECL);    /* and here for \v(filespec) */
  1607.     if (cx == XXSEN) {        /* SEND command */
  1608.         debug(F101,"Send: wild","",y);
  1609.         if (y == 0) {
  1610.         if ((x = cmtxt("Name to send it with","",&cmarg2,
  1611.                    xxstring)) < 0)
  1612.           return(x);
  1613.         } else {
  1614.         if ((x = cmcfm()) < 0) return(x);
  1615.         }
  1616.         cmarg = line;        /* File to send */
  1617.         debug(F110,"Sending:",cmarg,0);
  1618.         if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0);
  1619.     } else {            /* MAIL */
  1620. #ifndef NOFRILLS
  1621.         if (!atdiso || !atcapr) {    /* Disposition attribute off? */
  1622.         printf("?Disposition Attribute is Off\n");
  1623.         return(-2);
  1624.         }
  1625.         debug(F101,"Mail: wild","",y);
  1626.         *optbuf = NUL;        /* Wipe out any old options */
  1627.         if ((x = cmtxt("Address to mail to","",&s,xxstring)) < 0)
  1628.           return(x);
  1629.         if ((int)strlen(s) == 0) {
  1630.         printf("?Address required\n");
  1631.         return(-9);
  1632.         }
  1633.         strcpy(optbuf,s);
  1634.         if ((int)strlen(optbuf) > 94) { /* Ensure legal size */
  1635.         printf("?Option string too long\n");
  1636.         return(-2);
  1637.         }
  1638.         cmarg = line;        /* File to send */
  1639.         debug(F110,"Mailing:",cmarg,0);
  1640.         debug(F110,"To:",optbuf,0);
  1641.         rmailf = 1;            /* MAIL modifier flag for SEND */
  1642. #else
  1643.         printf("?Sorry, MAIL feature not configured.\n");
  1644.         return(-2);
  1645. #endif /* NOFRILLS */
  1646.     }
  1647.     sstate = 's';            /* Set start state to SEND */
  1648. #ifdef MAC
  1649.     scrcreate();
  1650. #endif /* MAC */
  1651.     if (local) {            /* If in local mode, */
  1652.         displa = 1;            /* turn on file transfer display */
  1653. #ifdef COMMENT
  1654. /* Redundant -- this is done later in sipkt() */
  1655.         ttflui();            /* and flush tty input buffer. */
  1656. #endif /* COMMENT */
  1657.     }
  1658.     return(0);
  1659.     }
  1660.  
  1661. #ifndef NOMSEND
  1662.     if (cx == XXMSE) {            /* MSEND command */
  1663.     nfils = 0;            /* Like getting a list of */
  1664.     lp = line;            /* files on the command line */
  1665.     while (1) {
  1666.         char *p;
  1667.         if ((x = cmifi("Names of files to send, separated by spaces","",
  1668.                &s,&y,xxstring)) < 0) {
  1669.         if (x == -3) {
  1670.             if (nfils <= 0) {
  1671.             printf("?A file specification is required\n");
  1672.             return(-9);
  1673.             } else break;
  1674.         }
  1675.         return(x);
  1676.         }
  1677.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  1678.         p = lp;            /* remember pointer, */
  1679.         while (*lp++ = *s++) ;    /* and copy it into buffer */
  1680.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  1681.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  1682.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < FSPECL) {
  1683.         strcat(fspec,p);
  1684.         strcat(fspec," ");
  1685.         }
  1686.     }
  1687.     cmlist = msfiles;        /* Point cmlist to pointer array */
  1688.     cmarg2 = "";            /* No internal expansion list (yet) */
  1689.     sndsrc = nfils;            /* Filenames come from cmlist */
  1690.     sstate = 's';            /* Set start state to SEND */
  1691. #ifdef MAC
  1692.     scrcreate();
  1693. #endif /* MAC */
  1694.     if (local) {            /* If in local mode, */
  1695.         displa = 1;            /* turn on file transfer display */
  1696.         ttflui();            /* and flush tty input buffer. */
  1697.     }
  1698.     return(0);
  1699.     }
  1700. #endif /* NOMSEND */
  1701.  
  1702. #ifndef NOSERVER
  1703.     if (cx == XXSER) {            /* SERVER */
  1704.     if ((x = cmcfm()) < 0) return(x);
  1705.     sstate = 'x';
  1706. #ifdef MAC
  1707.     scrcreate();
  1708. #endif /* MAC */
  1709.     if (local) displa = 1;
  1710. #ifdef AMIGA
  1711.     reqoff();            /* No DOS requestors while server */
  1712. #endif /* AMIGA */
  1713.     return(0);
  1714.     }
  1715. #endif /* NOSERVER */
  1716.  
  1717.     if (cx == XXSET) {            /* SET command */
  1718.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  1719.     if (x == -3) {
  1720.         printf("?You must specify a parameter to set\n");
  1721.         return(-9);
  1722.     }
  1723.     if (x < 0) return(x);
  1724.     /* have to set success separately for each item in doprm()... */
  1725.     /* actually not really, could have just had doprm return 0 or 1 */
  1726.     /* and set success here... */
  1727.     y = doprm(x,0);
  1728.     if (y == -3) {
  1729.         printf("?More fields required\n");
  1730.         return(-9);
  1731.     } else return(y);
  1732.     }
  1733.  
  1734. #ifndef NOPUSH
  1735.     if (cx == XXSHE) {            /* SHELL (system) command */
  1736.     if (cmtxt("System command to execute","",&s,xxstring) < 0)
  1737.       return(-1);
  1738.     conres();            /* Make console normal  */
  1739.     x = zshcmd(s);
  1740.     concb((char)escape);
  1741.     return(success = x);
  1742.     }
  1743. #endif /* NOPUSH */
  1744.  
  1745. #ifndef NOSHOW
  1746.     if (cx == XXSHO) {            /* SHOW */
  1747.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  1748.     if (x < 0) return(x);
  1749.     return(doshow(x));
  1750.     }
  1751. #endif /* NOSHOW */
  1752.  
  1753. #ifndef MAC
  1754.     if (cx == XXSPA) {            /* SPACE */
  1755. #ifdef datageneral
  1756.     /* AOS/VS can take an argument after its "space" command. */
  1757.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  1758.       return(x);
  1759.     if (*s == NUL) xsystem(SPACMD);
  1760.     else {
  1761.         sprintf(line,"space %s",s);
  1762.         xsystem(line);
  1763.     }
  1764. #else
  1765. #ifdef OS2
  1766.     if ((x = cmtxt("Press Enter for current disk,\n\
  1767.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  1768.       return(x);
  1769.     if (*s == NUL) {        /* Current disk */
  1770.         printf(" Free space: %ldK\n", zdskspace(0)/1024L);
  1771.     } else {
  1772.         int drive = toupper(*s);
  1773.         printf(" Drive %c: %ldK free\n", drive, 
  1774.            zdskspace(drive - 'A' + 1) / 1024L);
  1775.     }
  1776. #else
  1777. #ifdef UNIX
  1778. #ifdef COMMENT
  1779.     if ((x = cmtxt("Confirm for current disk,\n\
  1780.  or specify a disk device or directory","",&s,xxstring)) < 0)
  1781.       return(x);
  1782. #else
  1783.     x = cmdir("Confirm for current disk,\n\
  1784.  or specify a disk device or directory","",&s,xxstring);
  1785.     if (x == -3)
  1786.       s = "";
  1787.     else if (x < 0)
  1788.       return(x);
  1789.     if ((x = cmcfm()) < 0) return(x);
  1790. #endif /* COMMENT */
  1791.     if (*s == NUL) {        /* Current disk */
  1792.         xsystem(SPACMD);
  1793.     } else {            /* Specified disk */
  1794.         sprintf(line,"%s %s",SPACM2,s);
  1795.         xsystem(line);
  1796.     }
  1797. #else
  1798.     if ((x = cmcfm()) < 0) return(x);
  1799.     xsystem(SPACMD);
  1800. #endif /* UNIX */
  1801. #endif /* OS2 */
  1802. #endif /* datageneral */
  1803.     return(success = 1);        /* Pretend it worked */
  1804.     }
  1805. #endif /* MAC */
  1806.  
  1807.     if (cx == XXSTA) {            /* STATISTICS */
  1808.     if ((x = cmcfm()) < 0) return(x);
  1809.     return(success = dostat());
  1810.     }
  1811.  
  1812.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  1813.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  1814.       return(y);
  1815.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  1816.       return(y);
  1817.     if (*s == '{') {        /* Strip any enclosing braces */
  1818.         x = (int)strlen(s);
  1819.         if (s[x-1] == '}') {
  1820.         s[x-1] = NUL;
  1821.         s++;
  1822.         }
  1823.     }
  1824.     if (*s) printf("%s\n",s);
  1825.     if (cx == XXSTO) dostop(); else popclvl(); 
  1826.     return(success = (x == 0));
  1827.     }
  1828.  
  1829.     if (cx == XXSUS) {            /* SUSPEND */
  1830.     if ((y = cmcfm()) < 0) return(y);
  1831. #ifdef NOJC
  1832.     printf("Sorry, this version of Kermit cannot be suspended\n");
  1833. #else
  1834.     stptrap(0);
  1835. #endif /* NOJC */
  1836.     return(0);
  1837.     }
  1838.  
  1839.     if (cx == XXTAK) {            /* TAKE */
  1840.     if (tlevel > MAXTAKE-1) {
  1841.         printf("?Take files nested too deeply\n");
  1842.         return(-2);
  1843.     }
  1844.     if ((y = cmifi("C-Kermit command file","",&s,&x,xxstring)) < 0) { 
  1845.         if (y == -3) {
  1846.         printf("?A file name is required\n");
  1847.         return(-9);
  1848.         } else return(y);
  1849.     }
  1850.     if (x != 0) {
  1851.         printf("?Wildcards not allowed in command file name\n");
  1852.         return(-9);
  1853.     }
  1854.     strcpy(line,s);
  1855.     if ((y = cmcfm()) < 0) return(y);
  1856.     return(success = dotake(line));
  1857.     }
  1858.  
  1859. #ifdef NETCONN
  1860.     if (cx == XXTEL) {            /* TELNET */
  1861.     if ((y = setlin(XYHOST,0)) < 0) return(y);
  1862.     return (success = (y == 0) ? 0 : doconect());
  1863.     }
  1864. #endif /* NETCONN */
  1865.  
  1866. #ifndef NOXMIT
  1867.     if (cx == XXTRA) {            /* TRANSMIT */
  1868.     if ((x = cmifi("File to transmit","",&s,&y,xxstring)) < 0) {
  1869.         if (x == -3) {
  1870.         printf("?Name of an existing file\n");
  1871.         return(-9);
  1872.         } else return(x);
  1873.     }
  1874.     if (y != 0) {
  1875.         printf("?Only a single file may be transmitted\n");
  1876.         return(-2);
  1877.     }
  1878.     strcpy(line,s);            /* Save copy of string just parsed. */
  1879.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1880.     debug(F111,"calling transmit",line,xmitp);
  1881.     return(success = transmit(line,(char)xmitp)); /* Do the command */
  1882.     }
  1883. #endif /* NOXMIT */
  1884.  
  1885. #ifndef NOFRILLS
  1886.     if (cx == XXTYP) {            /* TYPE */
  1887. #ifndef MAC
  1888.     char *tc;
  1889. #endif /* MAC */
  1890.     if ((x = cmifi("File to type","",&s,&y,xxstring)) < 0) {
  1891.         if (x == -3) {
  1892.         printf("?Name of an existing file\n");
  1893.         return(-9);
  1894.         } else return(x);
  1895.     }
  1896.     if (y != 0) {
  1897.         printf("?A single file please\n");
  1898.         return(-2);
  1899.     }
  1900. #ifndef MAC
  1901.     if (!(tc = getenv("CK_TYPE"))) tc = TYPCMD;
  1902.     sprintf(line,"%s %s",tc,s);
  1903.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1904.     xsystem(line);
  1905.     return(success = 1);
  1906. #else
  1907.     strcpy(line,s);
  1908.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1909.     return(success = dotype(line));
  1910. #endif /* MAC */
  1911.     }
  1912. #endif /* NOFRILLS */
  1913.  
  1914. #ifndef NOFRILLS
  1915.     if (cx == XXTES) {            /* TEST */
  1916.     /* Fill this in with whatever is being tested... */
  1917.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1918.  
  1919. #ifndef NOSPL
  1920. #ifdef COMMENT
  1921.     { int d, i, j;            /* Dump all arrays */
  1922.       char c, **p;
  1923.       for (i = 0; i < 27; i++) {
  1924.           p = a_ptr[i];
  1925.           d = a_dim[i];
  1926.           c = (i == 0) ? 64 : i + 96;
  1927.           if (d && p) {
  1928.           fprintf(stderr,"&%c[%d]\n",c,d);
  1929.           for (j = 0; j <= d; j++) {
  1930.               if (p[j]) {
  1931.               fprintf(stderr,"  &%c[%2d] = [%s]\n",c,j,p[j]);
  1932.               }
  1933.           }      
  1934.           }
  1935.       }
  1936.       }
  1937. #else /* Not COMMENT */
  1938.     printf("cmdlvl = %d, tlevel = %d, maclvl = %d\n",cmdlvl,tlevel,maclvl);
  1939.     if (maclvl < 0) {
  1940.         printf("%s\n",
  1941.          "Call me from inside a macro and I'll dump the argument stack");
  1942.         return(0);
  1943.     }
  1944.     printf("Macro level: %d, ARGC = %d\n     ",maclvl,macargc[maclvl]);
  1945.     for (y = 0; y < 10; y++) printf("%7d",y);
  1946.     for (x = 0; x <= maclvl; x++) {
  1947.         printf("\n%2d:  ",x);
  1948.         for (y = 0; y < 10; y++) {
  1949.         s = m_arg[x][y];
  1950.         printf("%7s",s ? s : "(none)");
  1951.         }
  1952.     }
  1953.     printf("\n");
  1954. #endif /* COMMENT */
  1955. #endif /* NOSPL */
  1956.     return(0);
  1957.     }
  1958. #endif /* NOFRILLS */
  1959.  
  1960. #ifndef NOCSETS
  1961.     if (cx == XXXLA) {       /* TRANSLATE <ifn> from-cs to-cs <ofn> */
  1962.     int incs, outcs;
  1963.     if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) {
  1964.         if (x == -3) {
  1965.         printf("?Name of an existing file\n");
  1966.         return(-9);
  1967.         } else return(x);
  1968.     }
  1969.     if (y != 0) {
  1970.         printf("?A single file please\n");
  1971.         return(-2);
  1972.     }
  1973.     strcpy(line,s);            /* Save copy of string just parsed. */
  1974.  
  1975.     if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
  1976.       return(incs);
  1977.     if ((outcs = cmkey(fcstab,nfilc,"to character-set","",xxstring)) < 0)
  1978.       return(outcs);
  1979.     if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
  1980.     strncpy(tmpbuf,s,TMPBUFSIZ);
  1981.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1982.     return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */
  1983.     }
  1984. #endif /* NOCSETS */
  1985.  
  1986.     if (cx == XXVER) {            /* VERSION */
  1987.     if ((y = cmcfm()) < 0) return(y);
  1988.     printf("%s,%s\n Numeric: %ld",versio,ckxsys,vernum);
  1989.     if (verwho) printf("-%d\n",verwho); else printf("\n");
  1990.     return(success = 1);
  1991.     }
  1992.  
  1993. #ifndef MAC                /* Only for multiuser systems */
  1994. #ifndef NOFRILLS
  1995.     if (cx == XXWHO) {            /* WHO */
  1996.     char *wc;
  1997. #ifdef datageneral
  1998.         xsystem(WHOCMD);
  1999. #else
  2000.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  2001.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  2002.     sprintf(line,"%s %s",wc,s);
  2003.     xsystem(line);
  2004. #endif /* datageneral */
  2005.     return(success = 1);
  2006.     }
  2007. #endif /* NOFRILLS */
  2008. #endif /* MAC */
  2009.  
  2010. #ifndef NOFRILLS
  2011.     if (cx == XXWRI) {            /* WRITE */
  2012.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  2013.         if (x == -3) printf("?Write to what?\n");
  2014.         return(x);
  2015.     }
  2016.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  2017.     if (*s == '{') {        /* Strip enclosing braces */
  2018.         y = (int)strlen(s);
  2019.         if (s[y-1] == '}') {
  2020.         s[y-1] = NUL;
  2021.         s++;
  2022.         }
  2023.     }
  2024.     switch (x) {
  2025.       case LOGD: y = ZDFILE; break;
  2026.       case LOGP: y = ZPFILE; break;
  2027.       case LOGS: y = ZSFILE; break;
  2028.       case LOGT: y = ZTFILE; break;
  2029. #ifndef NOSPL
  2030.       case LOGW: y = ZWFILE; break;
  2031. #endif /* NOSPL */
  2032.       case LOGX:
  2033.       case LOGE:
  2034.  
  2035. #ifndef MAC
  2036.         if (x == LOGE) fprintf(stderr,"%s",s);
  2037.         else
  2038. #endif /* MAC */
  2039.           printf("%s",s);
  2040.         if (
  2041. #ifndef NOSPL
  2042.         cmdlvl == 0
  2043. #else
  2044.         tlevel == -1
  2045. #endif /* NOSPL */
  2046.         )
  2047. #ifndef MAC
  2048.           if (x == LOGE) fprintf(stderr,"\n");
  2049.           else
  2050. #endif /* MAC */
  2051.         printf("\n");
  2052.         return(success = 1);
  2053.       default: return(-2);
  2054.     }
  2055.     if ((x = zsout(y,s)) < 0)
  2056.       printf("?File or log not open\n");
  2057.     return(success = (x == 0) ? 1 : 0);
  2058.     }
  2059. #endif /* NOFRILLS */
  2060.  
  2061.     debug(F101,"docmd unk arg","",cx);
  2062.     return(-2);                /* None of the above. */
  2063. } /* end of docmnd() */
  2064.  
  2065. #endif /* NOICP */
  2066.